<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Vanilla</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Vanilla' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../intern.html">Inter Modules</a></li><li><a href="index.html">final</a></li><li><a href="index.html#2">Chapter 2: Mechanism</a></li><li><b>Vanilla</b></li></ul></div>
<p class="purpose">The plain-vanilla code generation strategy, provided for the use of generators to imperative languages such as Inform 6 or C.</p>

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>The rest of this chapter is a plain-vanilla algorithm for turning Inter trees
to imperative code, making method calls to the generator to handle each individual
step as needed. I think this works quite elegantly, but then every beetle is a
gazelle in the eyes of its mother.
</p>

<p class="commentary">The following function does everything except that the generator has already been
sent the <span class="extract"><span class="extract-syntax">BEGIN_GENERATION_MTID</span></span> method, and that the generator will subsequently
be sent <span class="extract"><span class="extract-syntax">END_GENERATION_MTID</span></span>: see <a href="2-cg2.html#SP4" class="internal">Generators::go</a>.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Vanilla::go</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Vanilla::go</span></span>:<br/>Code Generators - <a href="2-cg2.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="2-vnl.html#SP1_1" class="named-paragraph-link"><span class="named-paragraph">Traverse for pragmas</span><span class="named-paragraph-number">1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><a href="2-cg2.html#SP18" class="function-link"><span class="function-syntax">Generators::declare_variables</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">gen</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">global_variables</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-vo.html#SP2" class="function-link"><span class="function-syntax">VanillaObjects::declare_properties</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-vf.html#SP1" class="function-link"><span class="function-syntax">VanillaFunctions::predeclare_functions</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="2-vnl.html#SP1_2" class="named-paragraph-link"><span class="named-paragraph">General traverse</span><span class="named-paragraph-number">1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><a href="2-vc.html#SP4" class="function-link"><span class="function-syntax">VanillaConstants::declare_text_literals</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-vo.html#SP4" class="function-link"><span class="function-syntax">VanillaObjects::declare_kinds_and_instances</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP1_1" class="paragraph-anchor"></a><b>&#167;1.1. </b>Since pragma settings may affect what the generator does (that is the point
of them, after all), we want to send those to the generator first of all. It
can act on them or ignore them as it pleases.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Traverse for pragmas</span><span class="named-paragraph-number">1.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">InterTree::traverse_root_only</span><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">from</span><span class="plain-syntax">, </span><a href="2-vnl.html#SP2" class="function-link"><span class="function-syntax">Vanilla::pragma</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">PRAGMA_IST</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-vnl.html#SP1">&#167;1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Vanilla::pragma</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Vanilla::pragma</span></span>:<br/><a href="2-vnl.html#SP1_1">&#167;1.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inter_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">state</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><a href="2-cg2.html#SP5" class="function-link"><span class="function-syntax">Generators::offer_pragma</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">PragmaInstruction::target</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">), </span><span class="identifier-syntax">PragmaInstruction::content</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP1_2" class="paragraph-anchor"></a><b>&#167;1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">General traverse</span><span class="named-paragraph-number">1.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">gen</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">void_level</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">InterTree::traverse</span><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">from</span><span class="plain-syntax">, </span><a href="2-vnl.html#SP3" class="function-link"><span class="function-syntax">Vanilla::iterate</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-vnl.html#SP1">&#167;1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>This looks for the top level of packages which are not the code-body of
functions, and calls <a href="2-vnl.html#SP4" class="internal">Vanilla::node</a> to recurse downwards through them.
En route we also spot the functions, and declare those.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Vanilla::iterate</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Vanilla::iterate</span></span>:<br/><a href="2-vnl.html#SP1_2">&#167;1.2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inter_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">state</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Inode::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">PACKAGE_IST</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">inter_package</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pack</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PackageInstruction::at_this_head</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">InterPackage::is_a_function_body</span><span class="plain-syntax">(</span><span class="identifier-syntax">pack</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><a href="2-vf.html#SP8" class="function-link"><span class="function-syntax">VanillaFunctions::declare_function</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">PackageInstruction::name_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">pack</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">inter_package</span><span class="plain-syntax"> *</span><span class="identifier-syntax">outer</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterPackage::container</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">outer</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">InterPackage::is_a_function_body</span><span class="plain-syntax">(</span><span class="identifier-syntax">outer</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Inode::get_construct_ID</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONSTANT_IST:</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">VARIABLE_IST:</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SPLAT_IST:</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INSTANCE_IST:</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROPERTYVALUE_IST:</span>
<span class="plain-syntax">                    </span><a href="2-vnl.html#SP4" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>The function <a href="2-vnl.html#SP4" class="internal">Vanilla::node</a> is a sort of handle-any-node function, and is
the main way we iterate through the Inter tree.
</p>

<p class="commentary">Note that the general-traverse iteration above calls into this function, but
that the function then recurses down through nodes. As a result, it sees pretty
well the entire tree by the end.
</p>

<p class="commentary">The current node is always called <span class="extract"><span class="extract-syntax">P</span></span>, for reasons now forgotten.
</p>

<p class="commentary">It is so often used recursively that the following abbreviation macros are helpful:
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">    </span><a href="2-vnl.html#SP4" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::first_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">))</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">    </span><a href="2-vnl.html#SP4" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::second_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">))</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">VNODE_3C</span><span class="plain-syntax">    </span><a href="2-vnl.html#SP4" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::third_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">))</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">VNODE_4C</span><span class="plain-syntax">    </span><a href="2-vnl.html#SP4" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::fourth_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">))</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">VNODE_5C</span><span class="plain-syntax">    </span><a href="2-vnl.html#SP4" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::fifth_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">))</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">VNODE_6C</span><span class="plain-syntax">    </span><a href="2-vnl.html#SP4" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::sixth_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">))</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">VNODE_7C</span><span class="plain-syntax">    </span><a href="2-vnl.html#SP4" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::seventh_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">))</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">VNODE_ALLC</span><span class="plain-syntax">  </span><span class="identifier-syntax">LOOP_THROUGH_INTER_CHILDREN</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">) </span><a href="2-vnl.html#SP4" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">)</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Vanilla::node</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Vanilla::node</span></span>:<br/><a href="2-vnl.html#SP3">&#167;3</a><br/>Inform 6 Code - <a href="4-i6c2.html#SP2">&#167;2</a>, <a href="4-i6c2.html#SP5">&#167;5</a>, <a href="4-i6c2.html#SP6">&#167;6</a>, <a href="4-i6c2.html#SP7_2_1_2">&#167;7.2.1.2</a>, <a href="4-i6c2.html#SP8">&#167;8</a>, <a href="4-i6c2.html#SP7_5_1">&#167;7.5.1</a>, <a href="4-i6c2.html#SP7_5_8">&#167;7.5.8</a><br/>C References - <a href="5-crf.html#SP2_1_1">&#167;2.1.1</a>, <a href="5-crf.html#SP2_1_2">&#167;2.1.2</a>, <a href="5-crf.html#SP2_1_3">&#167;2.1.3</a><br/>C Assembly - <a href="5-cas.html#SP6_2">&#167;6.2</a>, <a href="5-cas.html#SP6_3">&#167;6.3</a><br/>C Program Control - <a href="5-cpc.html#SP2_7">&#167;2.7</a>, <a href="5-cpc.html#SP3">&#167;3</a><br/>C Conditions - <a href="5-ccn.html#SP2">&#167;2</a>, <a href="5-ccn.html#SP2_1">&#167;2.1</a>, <a href="5-ccn.html#SP2_2">&#167;2.2</a><br/>C Function Model - <a href="5-cfm.html#SP5_1">&#167;5.1</a>, <a href="5-cfm.html#SP5_2">&#167;5.2</a>, <a href="5-cfm.html#SP8_1">&#167;8.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Inode::get_construct_ID</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONSTANT_IST:</span><span class="plain-syntax">      </span><a href="2-vc.html#SP1" class="function-link"><span class="function-syntax">VanillaConstants::constant</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>

<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LABEL_IST:</span><span class="plain-syntax">         </span><a href="2-vc2.html#SP2" class="function-link"><span class="function-syntax">VanillaCode::label</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CODE_IST:</span><span class="plain-syntax">          </span><a href="2-vc2.html#SP1" class="function-link"><span class="function-syntax">VanillaCode::code</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EVALUATION_IST:</span><span class="plain-syntax">    </span><a href="2-vc2.html#SP1" class="function-link"><span class="function-syntax">VanillaCode::evaluation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">REFERENCE_IST:</span><span class="plain-syntax">     </span><a href="2-vc2.html#SP1" class="function-link"><span class="function-syntax">VanillaCode::reference</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INV_IST:</span><span class="plain-syntax">           </span><a href="2-vc2.html#SP3" class="function-link"><span class="function-syntax">VanillaCode::inv</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CAST_IST:</span><span class="plain-syntax">          </span><a href="2-vc2.html#SP1" class="function-link"><span class="function-syntax">VanillaCode::cast</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">VAL_IST:</span><span class="plain-syntax">           </span><a href="2-vc2.html#SP4" class="function-link"><span class="function-syntax">VanillaCode::val_or_ref</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">REF_IST:</span><span class="plain-syntax">           </span><a href="2-vc2.html#SP4" class="function-link"><span class="function-syntax">VanillaCode::val_or_ref</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ASSEMBLY_IST:</span><span class="plain-syntax">      </span><a href="2-vc2.html#SP6" class="function-link"><span class="function-syntax">VanillaCode::assembly</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LAB_IST:</span><span class="plain-syntax">           </span><a href="2-vc2.html#SP5" class="function-link"><span class="function-syntax">VanillaCode::lab</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>

<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SPLAT_IST:</span><span class="plain-syntax">         </span><a href="2-vnl.html#SP5" class="function-link"><span class="function-syntax">Vanilla::splat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PACKAGE_IST:</span><span class="plain-syntax">       </span><span class="constant-syntax">VNODE_ALLC</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>

<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INSTANCE_IST:</span><span class="plain-syntax">      </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">VARIABLE_IST:</span><span class="plain-syntax">      </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROPERTYVALUE_IST:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOCAL_IST:</span><span class="plain-syntax">         </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NOP_IST:</span><span class="plain-syntax">           </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">COMMENT_IST:</span><span class="plain-syntax">       </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROVENANCE_IST:</span><span class="plain-syntax">    </span><a href="2-vc2.html#SP7" class="function-link"><span class="function-syntax">VanillaCode::place_provenance</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>

<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INVALID_IST:</span><span class="plain-syntax">       </span><span class="identifier-syntax">InterErrors::backtrace</span><span class="plain-syntax">(</span><span class="identifier-syntax">DL</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                                </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"INVALID node type in Inter tree"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">        </span><span class="identifier-syntax">default:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">InterInstruction::write_construct_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">DL</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unexpected node type in Inter tree"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b><span class="extract"><span class="extract-syntax">splat</span></span> nodes are the joker in the pack. They copy material verbatim to the
output, regardless of the language being generated. (In practice, of course, this
means that the content of a <span class="extract"><span class="extract-syntax">splat</span></span> must carefully have been pre-generated in
the right format.) Inform uses such nodes as little as it possibly can.
</p>

<p class="commentary">A wrinkle, though, is that the special <span class="extract"><span class="extract-syntax">URL_SYMBOL_CHAR</span></span> is used to mark out
a URL for a symbol in the Inter tree: this is replaced with its properly
generated name. So a splat is not quite generator-independent after all.
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">URL_SYMBOL_CHAR</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00A7</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Vanilla::splat</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Vanilla::splat</span></span>:<br/><a href="2-vnl.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> = </span><a href="2-cg.html#SP14" class="function-link"><span class="function-syntax">CodeGen::current</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inter_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">gen</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">from</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SplatInstruction::splatter</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-vnl.html#SP5" class="function-link"><span class="function-syntax">Vanilla::splat_matter</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Vanilla::splat_matter</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Vanilla::splat_matter</span></span>:<br/>Vanilla Objects - <a href="2-vo.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">L</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">inchar32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">URL_SYMBOL_CHAR</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">++; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">L</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">inchar32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">URL_SYMBOL_CHAR</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">symb</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterSymbolsTable::URL_to_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterSymbol::trans</span><span class="plain-syntax">(</span><span class="identifier-syntax">symb</span><span class="plain-syntax">));</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">PUT</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="2-cg2.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-cg.html">cg</a></li><li class="progresssection"><a href="2-cg2.html">cg2</a></li><li class="progresscurrent">vnl</li><li class="progresssection"><a href="2-vc.html">vc</a></li><li class="progresssection"><a href="2-vf.html">vf</a></li><li class="progresssection"><a href="2-vo.html">vo</a></li><li class="progresssection"><a href="2-vc2.html">vc2</a></li><li class="progresssection"><a href="2-vi.html">vi</a></li><li class="progresschapter"><a href="3-fti.html">3</a></li><li class="progresschapter"><a href="4-fi6.html">4</a></li><li class="progresschapter"><a href="5-fnc.html">5</a></li><li class="progressnext"><a href="2-vc.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

